package clusterapi

import (
	"context"
	_ "embed"
	"fmt"
	"os"
	"time"

	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/rand"

	"gopkg.openfuyao.cn/bkeadm/pkg/executor/k8s"
	"gopkg.openfuyao.cn/bkeadm/pkg/global"
	"gopkg.openfuyao.cn/bkeadm/utils/log"
)

var (
	//go:embed cluster-api.yaml
	clusterAPI []byte
	//go:embed cluster-api-bke.yaml
	clusterAPIBKE []byte
	//go:embed webhook-secrets.yaml
	certManager []byte
)

func DeployClusterAPI(repo, version string) error {
	var err error
	if global.K8s == nil {
		global.K8s, err = k8s.NewKubernetesClient("")
		if err != nil {
			return err
		}
	}

	certMangerFile := fmt.Sprintf("%s/tmpl/cert-manager.yaml", global.Workspace)
	clusterAPIFile := fmt.Sprintf("%s/tmpl/cluster-api.yaml", global.Workspace)
	clusterAPIBKEFile := fmt.Sprintf("%s/tmpl/cluster-api-bke.yaml", global.Workspace)
	err = os.WriteFile(certMangerFile, certManager, 0644)
	if err != nil {
		return err
	}
	err = os.WriteFile(clusterAPIFile, clusterAPI, 0644)
	if err != nil {
		return err
	}
	err = os.WriteFile(clusterAPIBKEFile, clusterAPIBKE, 0644)
	if err != nil {
		return err
	}
	time.Sleep(1 * time.Second)

	log.BKEFormat(log.INFO, "Install Certificate Management...")
	err = global.K8s.InstallYaml(certMangerFile, map[string]string{"repo": repo}, "")
	if err != nil {
		return err
	}
	client := global.K8s.GetClient()
	//cert:
	//	for {
	//		time.Sleep(time.Duration(rand.IntnRange(5, 20)) * time.Second)
	//		log.BKEFormat(log.INFO, "Wait for the certificate management container running...")
	//		pods, err := client.CoreV1().Pods("cert-manager").List(context.Background(), metav1.ListOptions{})
	//		if err != nil {
	//			continue
	//		}
	//		if len(pods.Items) == 0 {
	//			continue
	//		}
	//		for _, pod := range pods.Items {
	//			if pod.Status.Phase != corev1.PodRunning {
	//				if len(pod.Status.ContainerStatuses) > 0 {
	//					if pod.Status.ContainerStatuses[len(pod.Status.ContainerStatuses)-1].State.Waiting != nil {
	//						log.BKEFormat(log.WARN, fmt.Sprintf("Container %s status %s", pod.Name,
	//							pod.Status.ContainerStatuses[len(pod.Status.ContainerStatuses)-1].State.Waiting.Reason))
	//					}
	//				}
	//				goto cert
	//			}
	//		}
	//		log.BKEFormat(log.INFO, "Certificate management service container running")
	//		break
	//	}

	log.BKEFormat(log.INFO, "Install the Cluster API...")
	for {
		time.Sleep(5 * time.Second)
		err = global.K8s.InstallYaml(clusterAPIFile, map[string]string{"repo": repo}, "")
		if err != nil {
			log.BKEFormat(log.WARN, "Installation failed. Try again in 5 seconds")
			log.Debugf("err: %v", err)
			continue
		}
		break
	}
	err = global.K8s.InstallYaml(clusterAPIBKEFile, map[string]string{"repo": repo, "version": version}, "")
	if err != nil {
		return err
	}
cluster:
	for {
		time.Sleep(time.Duration(rand.IntnRange(5, 20)) * time.Second)
		log.BKEFormat(log.INFO, "Wait for the cluster-api container to running...")
		pods, err := client.CoreV1().Pods("cluster-system").List(context.Background(), metav1.ListOptions{})
		if err != nil {
			continue
		}
		if len(pods.Items) == 0 {
			continue
		}
		for _, pod := range pods.Items {
			if pod.Status.Phase != corev1.PodRunning {
				if len(pod.Status.ContainerStatuses) > 0 {
					if pod.Status.ContainerStatuses[len(pod.Status.ContainerStatuses)-1].State.Waiting != nil {
						log.BKEFormat(log.WARN, fmt.Sprintf("Container %s status %s", pod.Name,
							pod.Status.ContainerStatuses[len(pod.Status.ContainerStatuses)-1].State.Waiting.Reason))
					}
				}
				goto cluster
			}
		}
		log.BKEFormat(log.INFO, "Cluster-api container running")
		break
	}
	return nil
}
